
package com.beilang.base.util;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang.StringUtils;


public class StringUtil extends StringUtils {


    /**
     * Capitalizes a string, i.e. changing its first letter to uppercase.
     *
     * @param str The String that needs to be capitalized.
     * @return The capitalized string.
     */
    public static String capitalize(String str) {
        if (str == null || str.length() == 0)
            return str;
        else
            return str.substring(0, 1).toUpperCase() + str.substring(1);
    }



    /**
     * Combines the strings values in the string array into one single string,
     * delimited by the specified delimiter. An emtpy String is returned if
     * the given values array is of size 0.
     *
     * @param values    The strings to be combined.
     * @param delimiter The delimiter used to separate the different strings.
     * @return The resultant string combined from the string array separated by
     *         the specified delimiter. Return an emtpy String if the given
     *         values array is of size 0.
     * @throws NullPointerException if the values argument is <code>null</code>
     */
    public static String combine(String[] values, String delimiter) {

        if (values == null) {
            throw new NullPointerException("values array is null");
        }

        if (values.length == 0) {
            return "";
        }

        StringBuffer result = new StringBuffer();

        for (int i = 1; i < values.length; i++) {
            result.append(delimiter);
            result.append(values[i]);
        }

        result.insert(0, values[0]);

        return result.toString();
    }

    /**
     * Removes redundant spaces (the second consecutive space onwards) from a String.
     *
     * @param str The String that needs to be compacted.
     * @return The String which has been compacted.
     */
    public static String compact(String str) {
        if (str == null || str.length() == 0)
            return str;

        int len = str.length();
        char buf[] = new char[len];
        StringBuffer sb = new StringBuffer();
        str.getChars(0, len, buf, 0);
        int i = 0;

        while (i < len) {
            if (buf[i] != ' ') /* Found the first space */
                sb.append(buf[i++]);
            else {
                sb.append(' ');
                while (i < len && buf[i] == ' ') /* Skip the rest of the spaces */
                    i++;
            }
        }

        return sb.toString();
    }

    /**
     * If a string is null, return it as "".
     *
     * @param str The String that needs to be checked for null value.
     * @return The String that is converted to appropriate string value.
     */
    public static String deNull(String str) {
        if (str == null)
            return "";
        return str;
    }

    /**
     * To return a string which is filled with a specified string.
     * e.g. duplicate("*", 5) returns "*****", duplicate("OK", 3) returns "OKOKOK"
     * repeated for given number of times
     *
     * @param str   String to be repeated/duplicated
     * @param times Number of time the string to be repeated/duplicated
     * @return The resulted string with <code>str</code> repeated the specified number of times.
     */
    public static String duplicate(String str, int times) {
        StringBuffer result = new StringBuffer();

        for (int i = 0; i < times; i++) {
            result.append(str);
        }
        return (result.toString());
    }

    /**
     * Get the count of occurrences of the character in the target string.
     *
     * @param str The String used to check for the character occurrenct count.
     * @param ch  The character to be counted in the string.
     * @return Number of occurrences of the character in the target string.
     */
    public static int getCount(String str, char ch) {
        int pos;
        int count = 0;

        do {
            pos = str.indexOf(ch);

            if (pos != -1) {
                count++;

                if (pos != str.length())
                    str = str.substring(pos + 1, str.length());
                else
                    pos = -1;
            }

        } while (pos != -1);

        return count;
    }

    /**
     * Checks if the length of the string is of the length specified.
     *
     * @param str The string to test for the length.
     * @param len The length that the string should conform to.
     * @return A boolean value that indicates if the string is of the length specified.
     */
    public static boolean isLengthEqual(String str, int len) {
        if (str == null) {
            return false;
        } // if (str == null)

        return (str.length() == len) ? true : false;
    }

    /**
     * Tests whether the specified string's length is less than or equal to the
     * specified length.
     *
     * @param str The string to test for the length.
     * @param len The length that the string should conform to.
     * @return A boolean value that indicates if the string is at most the length specified.
     */
    public static boolean isLengthLessThan(String str, int len) {
        if (str == null) {
            return false;
        } // if (str == null)

        return (str.length() <= len) ? true : false;
    }

    /**
     * Returns true if the data is null or empty string
     *
     * @param data
     * @return
     */
    public static boolean isNullOrEmpty(String data) {
        return data == null || data.length() == 0;
    }

    /**
     * Returns true if the data is null or empty string array (length == 0)
     *
     * @param data
     * @return
     */
    public static boolean isNullOrEmpty(String[] data) {
        return data == null || data.length == 0;
    }

    /**
     * Returns true if the data is  null or blank string (with only whitespaces)
     *
     * @param data
     * @return
     */
    public static boolean isNullOrBlank(String data) {
        return data == null || isBlank(data);
    }

    /**
     * Returns true if the data equals to data2 or both are null.
     *
     * @param data
     * @return
     */
    public static boolean isEqual(String data1, String data2) {
        if (data1 == null && data2 == null) return true;
        else if (data1 != null) return data1.equals(data2);
        else return data2.equals(data1);
    }

    public static boolean isEqualTrim(String data1, String data2) {
        data1 = data1 == null ? data1 : data1.trim();
        data2 = data2 == null ? data2 : data2.trim();
        return isEqual(data1, data2);

    }

    /**
     * Returns true if the data equals to data2.
     *
     * @param data
     * @return
     */
    public static boolean isEqualNotNull(String data1, String data2) {
        if (data1 == null || data1.length() == 0 || data2 == null || data2.length() == 0) return false;
        else return data2.equals(data1);
    }

    public static boolean isBiggerThanZero(int data1, int data2) {
        if (data1 > 0 || data2 > 0) {
            return true;
        } else
            return false;
    }

    public static String padZeroFront(String data) {
        if (data.length() < 2) {
            data = "0" + data;
        }
        return data;
    }

    /**
     * Returns true if the data equals int 0
     *
     * @param data
     * @return
     */
    public static boolean isEqualZero(int data1, int data2) {

        if (data1 == 0 && data2 == 0) {
            return true;
        } else
            return false;
    }

    /**
     * Returns true if the data equals to data2 or both are null.
     *
     * @param data
     * @return
     */
    public static boolean isEqualIgnoreCase(String data1, String data2) {
        if (data1 == null && data2 == null) return true;
        else if (data1 != null) return data1.equalsIgnoreCase(data2);
        else return data2.equalsIgnoreCase(data1);
    }

    /**
     * To pad the given string with a user specified character on the left up to the
     * given length.
     * e.g. lPad("ABCD", 10, 'X') returns "XXXXXXABCD" which has a length of 10.
     * This method has built-in 'intelligence' to handle cases where calling method
     * If <I>str</I> already longer than <I>length</I>, return <I>str</I> itself.
     * tries to be funny and supply the following :
     * - lPad("abc", 10, "123") it will return, "1231231abc"
     *
     * @param str       String to be padded
     * @param length    he required length of the resulted string.
     * @param padString The required padding string
     * @return The padded string
     */
    public static String lPad(String str, int length, String padString) {
        int lOriginal = str.length();
        int lPadStr = padString.length();
        int times2Pad = 0;
        int lPadded = 0;

        if (lOriginal >= length)
            return str;

        StringBuffer sb = new StringBuffer();
        String padded;

        times2Pad = (length - lOriginal) / lPadStr;  //will give (1) if 3/2

        padded = duplicate(padString, times2Pad);
        lPadded = padded.length();
        sb.append(padded);        //pad in the repetitive characters

        //if still insufficient by the modulus e.g. 30/20 is 10
        if (lOriginal + lPadded < length) {
            int more = length - (lOriginal + lPadded);

            //add in the difference which is less entire length of padStr
            sb.append(padString.substring(0, more));
        }

        sb.append(str); //pad the original string behind

        return sb.toString();
    }

    /**
     * Pads the string with prevailing spaces.
     *
     * @param str String to be padded with spaces on the left.
     * @param len The number of spaces to pad to the left of the string.
     * @return The space-padded string.
     */
    public static String lPad(String str, int len) {
        return lPad(str, len, " ");
    }

    /**
     * Remove all occurrences of the match in the target string.
     *
     * @param str   The String to be checked and have the occurrences of the matching String removed.
     * @param match The matching string.
     * @return The resultant string with all matching string removed.
     */
    public static String removeAllMatch(String str, String match) {

        if (str == null || match == null || str.length() == 0 || match.length() == 0) {
            return "";
        }

        StringBuffer newStr = new StringBuffer();

        int endpos = 0;
        for (int startpos = str.indexOf(match, endpos); startpos != -1; startpos = str.indexOf(match, endpos)) {
            newStr.append(str.substring(endpos, startpos));
            endpos = startpos + match.length();
        }

        newStr.append(str.substring(endpos));

        return newStr.toString();
    }

    /**
     * Replace the occurrence of a key within the existing string with the required
     * value.
     *
     * @param str         Existing String to be replace
     * @param key         Key within the String to be searched and replaced
     * @param replacement The replaced value
     * @return The resulted string
     */
    public static String replaceAll(String str, String key, String replacement) {

        // Split the string with the key as the delimiter
        StringBuffer sb = new StringBuffer();
        if (StringUtils.isNotEmpty(str)) {
            String[] parts = StringUtil.split(str, key);
            sb.append(parts[0]);
            for (int i = 1; i < parts.length; i++) {
                sb.append(replacement + parts[i]);
            }
        }
        return sb.toString();
    }

    /**
     * Replaces the first substring of this string that matches the given key with the
     * given replacement.
     *
     * @param str         The String to be replaced
     * @param key         Key within the String to be searched and replaced
     * @param replacement The String used to replace
     * @return The String with the first occurence of the key value replaced.
     */
    public static String replaceFirst(String str, String key, String replacement) {
        StringBuffer result = new StringBuffer(str);

        int pos = str.indexOf(key);

        if (pos >= 0) {
            result.replace(pos, pos + key.length(), replacement);
            //System.out.println( "result = " + result );
        }
        return result.toString();
    }

    /**
     * Replaces the last substring of this string that matches the given key with the
     * given replacement.
     *
     * @param str         The String to be replaced
     * @param key         Key within the String to be searched and replaced
     * @param replacement The String used for replacement
     * @return The String with the last occurence of the key value replaced.
     */
    public static String replaceLast(String str, String key, String replacement) {
        StringBuffer result = new StringBuffer(str);

        int pos = str.lastIndexOf(key);

        if (pos >= 0) {
            result.replace(pos, pos + key.length(), replacement);
            System.out.println("result = " + result);
        }
        return result.toString();
    }

    /**
     * To pad the given string with spaces up to the given length. <br>
     * e.g. rPad("ABCD", 10, ' ') returns "ABCD      " which has a length of 10.
     * <p/>
     * This method has built-in 'intelligence' to handle cases where
     * calling method tries to be funny and supply the following<br>
     * - rPad("abc", 10, "123") it will return, "abc1231231"
     *
     * @param str       String to be padded
     * @param length    The required length of the resulted string
     * @param padString The required padding string.
     * @return The padded string.
     *         If str already <I>longer</I> than <I>length</I>, return str itself.
     */
    public static String rPad(String str, int length, String padString) {
        int lOriginal = str.length();
        int lPadStr = padString.length();
        int times2Pad = 0;
        int lPadded = 0;

        if (lOriginal >= length)
            return str;

        StringBuffer sb = new StringBuffer(str); //add the original str first
        String padded;

        times2Pad = (length - lOriginal) / lPadStr;  //will give (1) if 3/2

        padded = duplicate(padString, times2Pad);
        lPadded = padded.length();
        sb.append(padded);        //pad in the repetitive characters

        //if still insufficient by the modulus e.g. 30/20 is 10
        if (lOriginal + lPadded < length) {
            int more = length - (lOriginal + lPadded);

            //add in the difference which is less entire length of padStr
            sb.append(padString.substring(0, more));
        }

        return sb.toString();
    }

    /**
     * Pads the string with following spaces.
     *
     * @param str The String to be padded with spaces on the right.
     * @param len The number of spaces to pad to the right of the string.
     * @return The resultant string with spaces padded on the right.
     */
    public static String rPad(String str, int len) {
        return rPad(str, len, " ");
    }



    public static String listToString(List oList, String separator, int separatorFrPos) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < oList.size(); i++) {
            if (i > separatorFrPos) {
                sb.append(separator);
            }
            sb.append(oList.get(i));
        }
        return sb.toString();
    }

    public static boolean contains(String[] array, String s) {
        return (indexOf(array, s) > -1);
    }

    public static int indexOf(String[] array, String s) {
        for (int i = 0; i < array.length; i++) {
            if (s != null && s.equals(array[i]))
                return i;
        }
        return -1;
    }

    public static String[] unite(String[] array1, String[] array2) {
        String[] result = new String[(array1 == null ? 0 : array1.length) + (array2 == null ? 0 : array2.length)];
        for (int i = 0; i < array1.length; i++)
            result[i] = array1[i];
        for (int i = 0; i < array2.length; i++)
            result[array1.length + i] = array2[i];

        return result;
    }

    /*
        public static void main ( String[] args ) {
            String mystring = "<PSiRequestEnvelope>This is a test.\nTest test test.</PSiRequestEnvelope>";

            mystring = StringUtil.removeAllMatch( mystring, "</PSiRequestEnvelope>" );
            System.out.println( "mystring = " + mystring );
        }
    */
    /**
     * This method is used to escape SQL string in a like clause
     */

    public static String escapeSQLString(String oldString) {
        if (oldString == null) return oldString;
        StringBuffer newString = new StringBuffer();
        char c;
        for (int i = 0; i < oldString.length(); i++) {
            c = oldString.charAt(i);
            switch (c) {
                case '\'': {
                    //if( i+1== oldString.length() || i+1< oldString.length() && oldString.charAt(i+1)!='\'')
                    newString.append("''");
                    break;
                }
                case '%': {
                    newString.append("/%");
                    break;
                }
                case '_': {
                    newString.append("/_");
                    break;
                }
                case '/': {
                    newString.append("//");
                    break;
                }
                default: {
                    newString.append(c);
                }
            }
        }
        return "%" + newString + "%";
    }


    /**
     * " => \" , \ => \\
     *
     * @param s
     * @return
     */
    public static String escapeJSONString(String s) {
        if (s == null)
            return null;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            switch (ch) {
                case '"':
                    sb.append("\\\"");
                    break;
                case '\\':
                    sb.append("\\\\");
                    break;
                case '\b':
                    sb.append("\\b");
                    break;
                case '\f':
                    sb.append("\\f");
                    break;
                case '\n':
                    sb.append("\\n");
                    break;
                case '\r':
                    sb.append("\\r");
                    break;
                case '\t':
                    sb.append("\\t");
                    break;
                case '/':
                    sb.append("\\/");
                    break;
                default:
                    if (ch >= '\u0000' && ch <= '\u001F') {
                        String ss = Integer.toHexString(ch);
                        sb.append("\\u");
                        for (int k = 0; k < 4 - ss.length(); k++) {
                            sb.append('0');
                        }
                        sb.append(ss.toUpperCase());
                    } else {
                        sb.append(ch);
                    }
            }
        }//for
        return sb.toString();
    }

    public static String filter(String input) {
        return StringUtil.filter(input, false);
    }

    public static String filter(String input, boolean convert) {
        if (input != null) {
            StringBuffer filtered = new StringBuffer(input.length());
            char c;
            for (int i = 0; i < input.length(); i++) {
                c = input.charAt(i);
                if (c == '<') {
                    filtered.append("&lt;");
                } else if (c == '>') {
                    filtered.append("&gt;");
                } else if (c == '"') {
                    filtered.append("&quot;");
                } else if (c == '&') {
                    filtered.append("&amp;");
                } else if (convert && c == '\n') {
                    filtered.append("<br>");
                } else {
                    filtered.append(c);
                }
            }
            return (filtered.toString());
        } else {
            return null;
        }
    }

    public static String shiftLastAlphabets(String id) {
        if (id == null || "".equals(id) || id.length() <= 1)
            return id;

        int firstNumberPosition = 0;
        int lastNumberPosition = id.length() - 1;

        while (firstNumberPosition < id.length() && Character.isLetter(id.charAt(firstNumberPosition)))
            firstNumberPosition++;
        while (lastNumberPosition >= 0 && Character.isLetter(id.charAt(lastNumberPosition)))
            lastNumberPosition--;


        if (firstNumberPosition > lastNumberPosition)
            return id;

        StringBuffer sb = new StringBuffer();
        sb.append(id.substring(0, firstNumberPosition));
        sb.append(id.substring(lastNumberPosition + 1, id.length()));
        sb.append(id.substring(firstNumberPosition, lastNumberPosition + 1));
        return sb.toString();
    }

    /**
     * For removing specified value from a array
     *
     * @param fieldList
     * @param exludeElement
     * @return
     */
    public static String[] removeFromArray(String[] fieldList, String exludeElement) {
        String[] newList = new String[fieldList.length - 1];
        List oldList = null;
        int j = 0;

        if (fieldList != null) {
            oldList = Arrays.asList(fieldList);
            if (!oldList.contains(exludeElement)) {
                return fieldList;
            }
            for (int i = 0; i < fieldList.length; i++) {
                if (!exludeElement.equals(fieldList[i])) {
                    newList[j] = fieldList[i];
                    j++;
                }
            }
            return newList;
        } else {
            return null;
        }
    }

    public static String getCommaSeparatedSQLString(String[] arrayOfString) {
        ArrayList list = new ArrayList();
        for (int i = 0; i < arrayOfString.length; i++) {
            list.add(arrayOfString[i]);
        }
        return getCommaSeparatedSQLString(list);
    }

    public static String getCommaSeparatedSQLString(List listOfString) {
        StringBuffer sqlStringBuffer = new StringBuffer();
        for (int i = 0; listOfString != null & i < listOfString.size(); i++) {
            String str = (String) listOfString.get(i);
            if ((str != null) && (str.trim().length() != 0)) {
                if (i > 0) {
                    sqlStringBuffer.append(",");
                }
                sqlStringBuffer.append("'");
                sqlStringBuffer.append(str);
                sqlStringBuffer.append("'");
            }
        }
        if (sqlStringBuffer.length() == 0) sqlStringBuffer.append("''");
        return sqlStringBuffer.toString();
    }

    public static boolean isConvertableToInteger(String s) {
        if (isNullOrBlank(s)) return false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!Character.isDigit(c)) return false;
        }

        return true;
    }

    public static String[] toUpperCase(String[] list) {
        if (isNullOrEmpty(list)) return list;
        String[] newList = new String[list.length];
        for (int i = 0; i < list.length; i++) {
            newList[i] = list[i].toUpperCase();
        }
        return newList;
    }

    /**
     * The format method that for the String
     *
     * @param value the string value
     * @return the string format value, when the value is null, it returns empty string("")
     */
    public static String formatString(String value) {
        if (value == null) {
            value = "";
        }
        return value.trim();
    }

    /**
     * The format method that remove the single quote from string
     *
     * @param value the string value
     * @return the string format value, when the value is null, it returns empty string("")
     */
    public static String removeSingleQuote(String value) {
        if (value == null) {
            value = "";
        }
        return value.trim().replace("'", "");
    }

    public static String convertEmpty2Null(String str) {
        if (str == null || str.trim().equalsIgnoreCase("")) return null;
        return str;
    }

    public static String formatPlainEmailContent(String content) {
        if (content == null || content.trim().equalsIgnoreCase("")) return "";
        content = content.replaceAll(" ", "&nbsp;");
        content = content.replaceAll("\r\n", "<br>");
        return content;
    }

     public static String splitString(String param) {
            if (param!=null&&param.length()>2)
            {
                String s = param.substring(1,2);
                if ("|".equals(s))
                {
                    return param.substring(2,param.length());
                }else if (param.length()>5)
                {
                   String s1= param.substring(4,5);
                    if ("|".equals(s1))
                    {
                       return param.substring(5,param.length());
                    }
                }
            }
            return param;
    }


}
